#pragma once
#include "common.h"
#include <errno.h>
// 设置文件描述符为非阻塞
static bool setFdNoBlock(int fd)
{
    int flags;

    if ((flags = fcntl(fd, F_GETFL)) == -1)
    {
        return false;
    }
    if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
    {
        return false;
    }
    return true;
}
// 循环读
/*
 * 返回值：
 *   >0代表读取的字节数
 *   ==0 对端关闭了
 *   ==-1读出错
 */
static int aeRead(int fd, string &inbuf)
{
    char buf[IO_BUFFER] = {0};
    int total = 0;
    while (1)
    {
        int nums = read(fd, buf, IO_BUFFER);
        if (nums > 0)
        {
            total += nums;
            inbuf.append(buf, nums);
            buf[0] = 0;
        }
        else if (nums == 0)
        {
            return 0;
        }
        else if (nums == -1)
        {
            if (errno == EAGAIN || errno == EWOULDBLOCK) // 读完了
                return total;
            else if (errno == EINTR) // 被信号中断，继续读
                continue;
            else
                return -1; // 出错了
        }
        else
            assert(false);
    }
}
// 循环写
/*
 * 大于等于0 成功
 */
static int aeWrite(int fd,const string &outbuf)
{
    const char *start = outbuf.c_str();
    int leftWriteBytes = outbuf.size();
    while (1)
    {
        int nums = write(fd, start, leftWriteBytes);
        if (nums > 0)
        {
            leftWriteBytes -= nums;
            start += nums;
        }
        else if (nums == 0)
        {
            return outbuf.size() - leftWriteBytes;//全部发完
        }
        else if (nums == -1)
        {
            if (errno == EAGAIN || errno == EWOULDBLOCK) // 缓冲区被打满了
                return outbuf.size() - leftWriteBytes;   // 返回已发送的字节数
            else if(errno == EINTR)
                continue;
            else
                return -1; // 出错
        }
        else
        {
            assert(false);
        }
    }
}

static void aeGetTime(long& sec,long& ms)
{
  struct timespec ts;
  clock_gettime(CLOCK_REALTIME, &ts);
  sec  = ts.tv_sec;
  ms = ts.tv_nsec / 1000000;
}
//获取当前时间戳，精度为毫秒
static long long aeGetTime()
{
  long sec,ms;
  aeGetTime(sec,ms);
  return sec*1000 + ms;  
}
static void aeAddTime(long& sec,long& ms,long addMs)
{
    ms+=addMs;
    if(ms>=1000)
    {
        sec += ms/1000;
        ms = ms%1000;
    }
}
//读一行，含CRLF
static int readLine(int fd,std::string& outbuf)
{
    char c;
    while (1)
    {
        int ret = read(fd,&c,1);

        if(ret<0) return -1;
        else if(ret==0) return 0;
        //cout<<c<<endl;
        if(c!='\r')
        outbuf+=c;
        else
        {
            outbuf+=c;
            read(fd,&c,1);
            outbuf+=c;
            break;
        }
    }

    return outbuf.size();
}